﻿Module mStatFunctions

    Public Sub PlayerHitPlayer(ByRef attackerconn As Connection, ByRef victimconn As Connection)

        If victimconn.IsAlive Then

            Dim rolldc As Single = CInt(Math.Floor((attackerconn.Stats.INT2_MAX_DC - attackerconn.Stats.INT2_MIN_DC + 1) * Rnd())) + attackerconn.Stats.INT2_MIN_DC
            Dim rollac As Single = CInt(Math.Floor((victimconn.Stats.INT2_MAX_AC - victimconn.Stats.INT2_MIN_AC + 1) * Rnd())) + victimconn.Stats.INT2_MIN_AC

            If rollac > 2 Then
                rollac = ((rollac * rollac) - (((rollac * rollac) * 2) / 3))
            End If
            Dim hitpoints As Integer = rolldc - rollac
            If hitpoints <= 0 Then
                hitpoints = 0
            End If
            If victimconn.GodMode Then hitpoints = 0

            SyncLock GetMapFromConn(victimconn).objMapLock

                victimconn.VitalPoints.HP -= hitpoints
                If victimconn.VitalPoints.HP <= 0 Then

                    'TODO: Murder
                    victimconn.VitalPoints.HP = 0
                    PlayerDies(victimconn)

                    Packets.SendSystemMessage(attackerconn, "Comitted murder!")
                    Packets.SendSystemMessage(victimconn, "Murdered by " & attackerconn.PlayerInfo.STR_NAME)

                End If

            End SyncLock

            UpdatePlayerHealth(victimconn)

        End If

    End Sub

    Public Sub PlayerHitMob(ByRef attackerconn As Connection, ByRef mob As MirMapMob)

        Dim rolldc As Single = CInt(Math.Floor((attackerconn.Stats.INT2_MAX_DC - attackerconn.Stats.INT2_MIN_DC + 1) * Rnd())) + attackerconn.Stats.INT2_MIN_DC
        Dim rollac As Single = CInt(Math.Floor((mob.stats.Stats.INT2_MAX_AC - mob.stats.Stats.INT2_MIN_AC + 1) * Rnd())) + mob.stats.Stats.INT2_MIN_AC

        If rollac > 2 Then
            rollac = ((rollac * rollac) - (((rollac * rollac) * 2) / 3))
        End If

        'fencing

        Dim fencinglvl As Integer = GetSkillLevel(attackerconn, Skills.Fencing) + 1

        If fencinglvl > 0 And fencinglvl < 4 Then
            If Int(Rnd() * 3) + 1 > 2 Then DoSkillXP(attackerconn, Skills.Fencing)
        End If

        '/fencing

        'spirit sword

        Dim spiritswordlvl As Integer = GetSkillLevel(attackerconn, Skills.Spiritsword) + 1

        If spiritswordlvl > 0 And spiritswordlvl < 4 Then
            If Int(Rnd() * 3) + 1 > 2 Then DoSkillXP(attackerconn, Skills.Spiritsword)
        End If

        '/spirits word

        'slaying

        Dim slayinglvl As Integer = GetSkillLevel(attackerconn, Skills.Slaying)

        If slayinglvl > -1 Then

            If Int(Rnd() * (10 + slayinglvl)) + 1 > 9 - (slayinglvl * 2) Then
                rolldc += (slayinglvl * 1.4) + 1
                Dim cast As MagicCast
                cast.magiccode = Protocol.Magics.Slaying
                cast.CharID = attackerconn.CharacterID
                CastMagic(cast, attackerconn)
                DoSkillXP(attackerconn, Skills.Slaying)
            End If

        End If

        '/slaying

        Dim rollacc As Integer = attackerconn.Stats.INT1_ACCURACY + slayinglvl + spiritswordlvl
        rollacc = rollacc + Int(Rnd() * 10)

        Dim hitpoints As Integer = rolldc - rollac
        If rollacc < 10 Then
            hitpoints = 0
        Else
            If hitpoints <= 0 Then
                hitpoints = 0
            End If
        End If

        mob.VitalPoints.HP -= hitpoints
        If mob.VitalPoints.HP > 0 Then
            If hitpoints > 0 Then
                mob.DoHitNextTick = True
                mob.AITargetType = TargetType.Player
                mob.AITargetIdx = attackerconn.CharacterID
                If mob.AIState <> 3 Then mob.AIState = 2
            End If
        Else

            AddExp(attackerconn, mob.stats.INT8_EXP)
            Drops.DoDrop(mob, attackerconn)

        End If

        Dim pkt As Packet
        Dim struct As MobHitInfo

        pkt.PacketType = GamePacketType.MobHit
        pkt.PacketOpCode = PacketOpCode.Notify
        pkt.Username = DefaultUsername

        struct.ServerMobID = mob.ServerMobID
        struct.VitalPoints = mob.VitalPoints

        SendToLocalPlayers(attackerconn, pkt, struct)

        'pkt.Username = attackerconn.Username

        'Socket.SockServer.SendData(Protocol.MakePacket(pkt, struct, attackerconn.Crypto), attackerconn.Index)

    End Sub

    Public Sub MobHitPlayer(ByRef mob As MirMapMob, ByRef victimconn As Connection)

        If victimconn.IsAlive Then

            Dim rolldc As Single = CInt(Math.Floor((mob.stats.Stats.INT2_MAX_DC - mob.stats.Stats.INT2_MIN_DC + 1) * Rnd())) + mob.stats.Stats.INT2_MIN_DC
            Dim rollac As Single = CInt(Math.Floor((victimconn.Stats.INT2_MAX_AC - victimconn.Stats.INT2_MIN_AC + 1) * Rnd())) + victimconn.Stats.INT2_MIN_AC

            If rollac > 2 Then
                rollac = ((rollac * rollac) - (((rollac * rollac) * 2) / 3))
            End If

            Dim hitpoints As Integer
            If rolldc > 0 Then hitpoints = mob.stats.Hit * ((rolldc - rollac) / rolldc)
            If hitpoints <= 0 Then
                hitpoints = 0
            End If
            If victimconn.GodMode Then hitpoints = 0

            SyncLock GetMapFromConn(victimconn).objMapLock

                victimconn.VitalPoints.HP -= hitpoints
                If victimconn.VitalPoints.HP < 1 Then
                    victimconn.VitalPoints.HP = 0
                    PlayerDies(victimconn)
                    Drops.DoDeathDrops(victimconn, Drops.DeathType.Mob)
                End If

            End SyncLock

            UpdatePlayerHealth(victimconn)

            'Test code for sending Mob Chat Msg
            'TODO find use for : mob.map.Mobs.MobSendChatMsg(victimconn, mob, "Ah Ha! Take That!", ChatMsgType.Normal)

        End If

    End Sub

    Public Sub PlayerMagicMob(ByRef attackerconn As Connection, ByRef mob As MirMapMob, ByVal magicstrength As Single, ByVal ele As Element, ByVal elestrength As Single)

        Dim rollmc As Single

        If ele = Element.Dark Or ele = Element.Holy Then
            rollmc = CInt(Math.Floor((attackerconn.Stats.INT2_MAX_SC - attackerconn.Stats.INT2_MIN_SC + 1) * Rnd())) + attackerconn.Stats.INT2_MIN_SC
        Else
            rollmc = CInt(Math.Floor((attackerconn.Stats.INT2_MAX_MC - attackerconn.Stats.INT2_MIN_MC + 1) * Rnd())) + attackerconn.Stats.INT2_MIN_MC
        End If

        Dim rollmac As Single = CInt(Math.Floor((mob.stats.Stats.INT2_MAX_MAC - mob.stats.Stats.INT2_MIN_MAC + 1) * Rnd())) + mob.stats.Stats.INT2_MIN_MAC

        If rollmac > 2 Then
            rollmac = ((rollmac * rollmac) - (rollmac * 1.5))
        End If

        rollmc *= magicstrength

        'Output.AddLine("(1) PlayerHitMob Roll MC: " & rollmc & "  MAC: " & rollmac)
        rollmc -= rollmac

        Dim elemental As Single

        Select Case ele
            Case Element.Fire
                elemental = CSng(attackerconn.Stats.INT2_ELEMC_FIRE) - CSng(mob.stats.Stats.INT2_ELEMAC_FIRE) + 1.0

        End Select

        If elemental > 0 Then elemental *= elestrength

        If elemental > 3 Then

            rollmc += (elemental * elemental) - (elemental * 2.5)

        ElseIf elemental = 3 Then

            rollmc += 4

        ElseIf elemental < 0 Then

            rollmc += (elemental / 1.5)

        Else

            rollmc += elemental

        End If

        'Output.AddLine("(2) PlayerHitMob Roll MC: " & rollmc & "  MAC: " & rollmac)

        Dim hitpoints As Integer = rollmc
        If hitpoints < 0 Then
            hitpoints = 0
        End If

        mob.VitalPoints.HP -= hitpoints
        If mob.VitalPoints.HP > 0 Then
            mob.DoHitNextTick = True
            mob.AITargetType = TargetType.Player
            mob.AITargetIdx = attackerconn.CharacterID
            If mob.AIState <> 3 Then mob.AIState = 2
        Else
            AddExp(attackerconn, mob.stats.INT8_EXP)
            Drops.DoDrop(mob, attackerconn)
        End If

        Dim pkt As Packet
        Dim struct As MobHitInfo

        pkt.PacketType = GamePacketType.MobHit
        pkt.PacketOpCode = PacketOpCode.Notify
        pkt.Username = DefaultUsername

        struct.ServerMobID = mob.ServerMobID
        struct.VitalPoints = mob.VitalPoints

        SendToLocalPlayers(attackerconn, pkt, struct)

    End Sub

    Public Sub DoHPnMPRegen(tc As Long)

        Static regenticks As Int64

        If regenticks = 0 Then regenticks = tc
        If regenticks < tc Then

            regenticks += 5000000

            For Each map As MirMap In mMaps.mMaps

                SyncLock map.objMapLock

                    For Each plyr As MirMapPlayer In map.Players
                        If plyr.conn.IsAlive Then
                            Dim changesdone As Boolean

                            With plyr.conn

                                'HP Regen
                                'check ticker
                                If .RegenStats.INT8_HPTICK + .RegenStats.INT8_HPSPEED < tc Then

                                    If .VitalPoints.HP < .VitalPoints.MAXHP Then

                                        .VitalPoints.HP += .RegenStats.INT8_HPAMMOUNT
                                        If .VitalPoints.HP > .VitalPoints.MAXHP Then .VitalPoints.HP = .VitalPoints.MAXHP

                                        changesdone = True

                                    End If

                                    .RegenStats.INT8_HPTICK = tc + .RegenStats.INT8_HPSPEED

                                End If

                                If .RegenStats.INT8_MPTICK + .RegenStats.INT8_MPSPEED < tc Then

                                    If .VitalPoints.MP < .VitalPoints.MAXMP Then

                                        .VitalPoints.MP += .RegenStats.INT8_MPAMMOUNT
                                        If .VitalPoints.MP > .VitalPoints.MAXMP Then .VitalPoints.MP = .VitalPoints.MAXMP

                                        changesdone = True

                                    End If

                                    .RegenStats.INT8_MPTICK = tc + .RegenStats.INT8_MPSPEED

                                End If

                            End With

                            If changesdone Then
                                UpdatePlayerHealth(plyr.conn, True)
                            End If

                        End If
                    Next

                End SyncLock

            Next

        End If

    End Sub

End Module

